#define _CRT_SECURE_NO_WARNINGS
#include "String.h"
namespace bit
{
    void string::reserve(size_t n)
    {
        if (n > _capacity)
        {
            char* cmp = new char[n + 1];
            strcpy(cmp, _str);
            delete[] _str;
            _str = cmp;
            _capacity = n;
        }
    }

    void string::push_back(char c)
    {
        //
        if (_capacity == _size)
        {
            reserve(_capacity == 0 ? 4 : _capacity * 2);
        }
        _str[_size] = c;
        _str[++_size] = '\0';
    }

    string& string::operator+=(char c)
    {
        push_back(c);
        return *this;
    }

    void string::append(const char* str)
    {
        int len = strlen(str);
        if (_size + len > _capacity)
        {
            reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);
        }
        strcpy(_str + _size, str);
        _size += len;
    }

    string& string::operator+=(const char* str)
    {
        append(str);
        return *this;
    }

    void string::resize(size_t n, char c)
    {
        for (int i = _size; i < n; i++)
        {
            *this += c;
        }
    }

    size_t string::find(char c, size_t pos) const
    {
        assert(pos < _size);
        for (int i = 0; i < _size; i++)
        {
            if (_str[i] == c)
                return i;
        }
        return npos;
    }

    size_t string::find(const char* s, size_t pos) const
    {
        assert(pos < _size);
        const char* P = strstr(_str + pos, s);
        if (P != nullptr)
        {
            return P - _str;
        }
        else
            return npos;
    }

    string& string::insert(size_t pos, char c)
    {
        assert(pos < _size);
        push_back(_str[_size - 1]);
        for (int i = _size - 2; i >= pos; i--)
        {
            _str[i + 1] = _str[i];
        }
        _str[pos] = c;
        return *this;
    }

    string& string::insert(size_t pos, const char* str)
    {
        assert(pos < _size);

        int len = strlen(str);

        for (int i = 0; i <len; i++)
        {
            insert(pos + i, str[i]);
        }
        return *this;
    }

    string& string::erase(size_t pos, size_t len)
    {
        assert(pos < _size);
        for (int i = pos; i < _size; i++)
        {
            _str[i] = _str[i + len];
        }
        return *this;
    }

    bool operator<(const string& s1,const string& s2)
    {
        return strcmp(s1.c_str(), s2.c_str()) < 0;
    }
    string string::substr(size_t pos , size_t len )
    {
        assert(pos < _size);
        string s1;
        int n = len;
        for (int i = pos; i < _size && n > 0; i++,n--)
        {
            s1.push_back(_str[i]);
        }
        return s1;
    }
};